package com.caiyi.financial.nirvana.sms.gateway.cmpp.cmpp20.handler;

import com.caiyi.financial.nirvana.sms.entity.SmsReceiveMessage;
import com.caiyi.financial.nirvana.sms.enums.SmsMsgStatusEnum;
import com.caiyi.financial.nirvana.sms.gateway.cmpp.CMPPHeader;
import com.caiyi.financial.nirvana.sms.gateway.cmpp.cmpp20.CMPPClient;
import com.caiyi.financial.nirvana.sms.gateway.cmpp.cmpp20.message.CMPPMessage;
import com.caiyi.financial.nirvana.sms.gateway.cmpp.cmpp20.message.body.*;
import com.caiyi.financial.nirvana.sms.jedis.JedisKey;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * CMPP接收消息控制器
 *
 * @author lvchaohua
 */
public class CMPPReceiverHandler extends SimpleChannelInboundHandler<CMPPMessage> {

    //日志
    private static final Logger logger = LogManager.getLogger(CMPPReceiverHandler.class);

    private CMPPClient client;

    public CMPPReceiverHandler(CMPPClient client) {
        this.client = client;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, CMPPMessage msg) throws Exception {
        int commandId = msg.getCommandID();
        switch (commandId) {

            //如果收到心跳包，不处理
            case CMPPMessage.CMPP_ACTIVE_TEST_RESP:
                logger.info(client.info.getName() + " 收到服务器心跳包回复。");
                break;

            //如果收到心跳包，回复网关
            case CMPPMessage.CMPP_ACTIVE_TEST:
                logger.info(client.info.getName() + " 收到服务器心跳包，回复心跳。");
                CMPPMessage messageTest = new CMPPMessage();
                messageTest.setSequenceId(msg.getSequenceId());
                messageTest.setCommandID(CMPPMessage.CMPP_ACTIVE_TEST_RESP);
                CMPPActiveTestResp activeTestResp = new CMPPActiveTestResp();
                messageTest.setBody(activeTestResp);
                ctx.writeAndFlush(messageTest);
                break;
            //连接回应
            case CMPPMessage.CMPP_CONNECT_RESP:
                handleCmppConnected((CMPPConnectionResp) msg.getBody());
                break;

            //获得上行短信
            case CMPPMessage.CMPP_DELIVER:
                CMPPDeliver deliver = (CMPPDeliver) msg.getBody();
                String accessNumber = deliver.getDestId();
                if (deliver.getIsDelivery() == 0) {
                    String remoteMsgId = Long.toHexString(deliver.getMessageId());
                    handleReceiveMessage(remoteMsgId, accessNumber, deliver.getSendPhone(), deliver.getMessageContent());
                } else {
                    handleCallbackMessage(deliver.getStat(), Long.toHexString(deliver.getReportMessageId()), deliver.getSendPhone());
                }
                responseDeliveryMessage(ctx, msg);
                break;

            //获得消息发送返回值
            case CMPPMessage.CMPP_SUBMIT_RESP:
                int seqId = msg.getSequenceId();
                CMPPSubmitResp resp = (CMPPSubmitResp) msg.getBody();
                String remoteMsgId = Long.toHexString(resp.getMessageId());
                handleSubmitResponse(resp.getResult(), seqId, remoteMsgId);
                break;
            default:
                break;
        }
    }


    /**
     * 处理上行消息
     */
    private void handleReceiveMessage(String remoteMsgId, String accessNumber, String sendPhone, String content) {
        logger.info("cmpp20 handleReceiveMessage accessNumber : {}, phone : {}, content : {}", accessNumber, sendPhone, content);
        String gatewayAccessNumber = client.info.getAccessNumber();
        String account = "";
        if (accessNumber.startsWith(gatewayAccessNumber)) {
            String extend = accessNumber.substring(gatewayAccessNumber.length());
            account = JedisService.get(String.format(JedisKey.SMS_EXTEND_ACCOUNT, extend));
        }
        SmsReceiveMessage message = new SmsReceiveMessage();
        message.setAccessNumber(accessNumber);
        message.setAccount(account);
        message.setContent(content);
        message.setMessageId(remoteMsgId);
        message.setPhone(sendPhone);
        client.receiveMessage(message);
    }

    /**
     * 处理回调消息
     */
    private void handleCallbackMessage(String result, String remoteMsgId, String phone) {
        logger.info("cmpp20 handleCallbackMessage result : {}, phone : {}, remoteMsgId : {}", result, phone, remoteMsgId);
        int status = SmsMsgStatusEnum.SEND_SUCCESS.index;
        if (!"DELIVERED".equals(result) && !"DELIVRD".equals(result)) {
            status = SmsMsgStatusEnum.SEND_FAIL.index;
        }
        String messageId = JedisService.hget(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteMsgId);
        JedisService.hdel(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteMsgId);
        if (StringUtils.isBlank(messageId)) {
            logger.warn("cmpp20 notifyStatus messageId is null phone : {}, remoteMsgId : {}", phone, remoteMsgId);
        }
        client.receiveReport(status, messageId, result);
    }

    /**
     * 发送回应处理
     */
    private void handleSubmitResponse(int result, int seqId, String remoteMsgId) {
        String messageId = client.S2M.remove(String.valueOf(seqId));
        int status = SmsMsgStatusEnum.REQUEST_SUCCESS.index;
        if (result != 0) {
            status = SmsMsgStatusEnum.REQUEST_FAIL.index;
            logger.info("cmpp20 handleSummitResponse remoteMsgId : {}, messageId : {}", remoteMsgId, messageId);
            client.onSubmitResponse(status, messageId, String.valueOf(result));
            return;
        }
        logger.info("handleSubmitResponse sequenceId : {}, remoteMsgId : {}, result : {}", seqId, remoteMsgId, result);
        JedisService.hset(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteMsgId, messageId);
        client.onSubmitResponse(status, messageId, remoteMsgId);
    }

    /**
     * 处理登录回应
     */
    private void handleCmppConnected(CMPPConnectionResp response) {
        int status = response.getStatus();
        if (status == 0) {
            client.loginSuccess();
            return;
        }
        if (status > 5) {
            status = 5;
        }
        client.loginFail(response.getStatus(), CMPPConnectionResp.STATUS.get(status));
    }

    /**
     * 处理上行短信
     */
    private void responseDeliveryMessage(ChannelHandlerContext context, CMPPMessage message) {

        CMPPMessage msg = new CMPPMessage();
        CMPPHeader header = new CMPPHeader();
        header.setCommandID(CMPPMessage.CMPP_DELIVER_RESP);
        header.setSequenceId(message.getSequenceId());
        msg.setHeader(header);
        CMPPDeliver deliver = (CMPPDeliver) message.getBody();
        CMPPDeliverResp resp = new CMPPDeliverResp();
        resp.setMessageId(deliver.getMessageId());
        resp.setResult((byte) 0);
        msg.setBody(resp);

        context.writeAndFlush(msg);

    }
}
